Массивы
-
одно из главных средств хранения в памяти компьютера
больших объемов информации.
Настоящего
программирования без массивов не бывает
В основе массивов лежит понятие индекса.
Переменные с
индексами
В
математике широко применяются так называемые индексированные переменные. На бумаге они записываются так:
Х1 Х2 b8 Zjj, а
читаются так: икс первое, икс второе, бэ восьмое,
игрек итое. Все эти маленькие подстрочные цифры и
выражения называются индексами. Поскольку в алфавите Visual Basic
нет подстрочных букв и цифр, то те
же индексированные переменные в Visual
Basic приходится
обозначать так:Х(1) Х(2)
В(8) Z(i,j).
Зачем математикам нужны индексированные
переменные? Их удобно применять хотя бы при операциях над числовыми рядами. Числовой
ряд - это просто несколько чисел, выстроенных по порядку одно за другим. Чисел
в ряду может быть много и даже бесконечно много.
Одномерные массивы переменных величин.
Одна из типичных задач
программирования формулируется примерно так. Имеется большое количество
данных, например тех же температур или высот. С этими данными компьютер должен
что-нибудь сделать, например вычислить среднегодовую
температуру, количество морозных дней, максимально взятую высоту и т. п.
Раньше мы уже вычисляли подобные вещи, и при этом данные вводили в компьютер с
клавиатуры одно за другим в одну и ту же ячейку памяти. Однако программистская
практика показывает, что удобно, а часто и необходимо иметь данные в
оперативной памяти сразу все, а не по очереди. Тогда для задачи про
температуру нам понадобится 365 ячеек. Эти 365 ячеек мы и назовем массивом. Итак, массивом
можно назвать ряд ячеек памяти, отведенных для хранения значений
индексированной переменной.
Рассмотрим на простом примере,
как Visual Basic управляется с массивами. Предположим, в зоопарке
живут 3 удава. Известна длина каждого удава в сантиметрах (500, 400 и 600).
Какая длина получится у трех удавов, вытянутых в линию?
Обозначим длину первого удава - dlina(1), второго
- dlina(2), третьего
- dlina(3). Прикажем
Visual Basic отвести под эту индексированную переменную массив
ячеек в памяти:
Dim dlina (1 То 3) As Integer
Здесь 1 - нижняя
граница индекса, 3 - верхняя граница индекса. Слово То обозначает
до. В целом эту строку можно перевести так: Отвести в
памяти под переменную dlina ряд ячеек типа Integer, пронумерованных от 1 до 3.
Мы видим, что значением переменной
величины является не одно число, а целый ряд чисел. Вот программа полностью: Dim dlina(1 То 3) As Integer
Dim summa As
Integer
Private Sub
Command1_Click()
dlina(1) = 500
dlina(2) = 400
dlina(3) = 600
summa = dlina(1) + dlina(2) + dlina(3)
Print summa
End Sub
Теперь запишем ту же программу в
предположении, что длины удавов заранее неизвестны и
мы их вводим при помощи InputBox.
Dim dlina(1 То 3) As
Integer
Private Sub
Command1_Click()
dlina(1) = InputВох("Введите длину 1-го удава")
dlina(2) = InputВох("Введите длину 2-го удава")
dlina(3) = InputBох("Введите длину 3-го
удава")
Print dlina(1) +
dlina(2) + dlina(3)
End Sub
Решим
еще одну задачу.
Дан ряд из 10 произвольных чисел: а(1), а(2)…а(10).
Подсчитать и
напечатать суммы восьми троек стоящих рядом чисел: а(1)+а(2)+а(3),
а(2)+а(3)+а(4), а(3)+а(4)+а(5),а(8)+а(9)+а(10).
Dim а(1 То 10) As Integer
Private Sub Command1_Click()
randomize
for i=1 to 10
a(i) =rnd*100
Next i
For i = 1 To 8
Print a(i) + a(i + 1) + a(i + 2)
Next
End Sub
Двумерные массивы
Поясним суть двумерных массивов
на простом примере. Пусть на целом ряде метеостанций, расположенных в разных
точках земного шара, в течение многих дней измеряли температуру воздуха. Показания
термометров свели в таблицу. Ограничимся для экономии места тремя станциями и
четырьмя днями.
|
1-й день |
2-й день |
3-й день |
4-й день |
Метеостанция 1 |
-8 |
-14 |
-19 |
-18 |
Метеостанция 2 |
25 |
28 |
26 |
20 |
Метеостанция 3 |
11 |
18 |
20 |
25 |
Требуется :
1. Распечатать температуру на 2-й метеостанции за 4-й
день и на 3-й метеостанции за 1 -й день.
2. Распечатать показания термометров всех метеостанций
за 2-й день.
3. Определить среднюю температуру на 3-й метеостанции.
4. Распечатать всю таблицу.
5. Распечатать, в какие дни и
на каких метеостанциях температура была в диапазоне
+24...26°С.
Для этого обозначим показания термометров
индексированной переменной с двумя индексами по следующей схеме:
t(1,1) t(1,2) t(1,3) t(1,4)
t(2,1) t(2,2) t(2,3) t(2,4) t(3,1)
t(3,2) t(3,3) t(3,4)
Обратите внимание, что 1-й индекс
в скобках обозначает номер строки (метеостанции), 2-й - номер столбца
(дня) прямоугольной таблицы. Такую таблицу математики называют матрицей.
В памяти отводим массив
из 3 * 4 = 12 ячеек под значения типа Integer
индексированной переменной t. Будем называть его двумерным массивом:
Dim t(1
То 3,1 То 4) As Integer
Private Sub Command1_Click()
'Зададим
значения элементов массива примитивным присваиванием:
t(1,1) = -8: t(1,2)
= -14: t(1,3) = -19: t(1, 4) = -18 t(2,1) = 25: t(2, 2) = 28: t(2,3) = 26: t(2,4) = 20 t(3T 1) = 11:
t(3, 2) = 18: t(3, 3) =
20: t(3,4)
= 25
'Выполняем 1-й
пункт задания:
Print t(2,4),t(3,1)
'А
теперь распечатаем 2-й столбец массива (2-й пункт):
For i = 1 То 3:
Print t(i, 2):
Next
'Определим
среднее значение элементов 3-й строки (3-й пункт):
i = 3
s = 0
For j = 1 То 4: '
s = s + t(i,j):
Next
Print s / 4
'Распечатаем всю таблицу (4-й пункт):
For i = 1 То 3
For j = 1 То 4
Print t(i, j), Next j
Print
Next i
'Распечатаем
станции и дни с температурой +24...2С (5-й пункт);
For i = 1 То 3
For j = 1 То 4
If t(i, j) >= 24 And t(i, j) <=
26 Then
Print "Станция"; i; "день"; j
Next j
Next i
End Sub
Какие бывают массивы
Массивы бывают не только
числовые, но и строковые, типа Date и
проч. Подходит любой известный нам тип. Например:
Dim s(1 То 50) As String
Это означает, что в каждой из 50 ячеек должно
находиться не число, а произвольная строка. Вот элементарный пример
использования строкового массива:
Dim s(1 То 50) As String
Private Sub Command1_Click()
s(21) = "Привет"
Print
s(21)
End
Sub
Вот
пример работы с массивами других типов:
Dim b(1
То 30,1 То 6) As Boolean
Dim DT(1 To 10) As
Date
Private Sub Command 1_Click()
b(2, 3) = False
Print b(2,3)
DT(2) = #1/15/2156 11:59:42 PM#:
Print DT(2)
End Sub
Границы индексов в круглых
скобках тоже могут быть разными, например:
Dim а(20 То 60) As Integer Здесь под числа отводится
41 ячейка.
Еще пример:
Dim b(0 То 9, -20 То 30) As Integer
Здесь под числа отводится 10*51=510 ячеек.
Если нижняя граница индекса вашего массива равна нулю, то вы можете
сэкономить усилия и вместо
Dim f(0 То 9) As
Integer написать Dim
f(9) As Integer
Задача.
Задан массив из 100 произвольных положительных чисел. Отсортировать его по возрастанию.
Идея решения. Если мы не можем сходу запрограммировать задачу, нужно подробно представить себе, в каком порядке мы решали бы ее вручную, без компьютера. Как бы мы сами сортировали 100 чисел? Мы бы запаслись пустым листом бумаги из 100 клеток. Затем нашли бы в исходном массиве максимальное число и записали его в самую правую клетку, а в исходном массиве на его месте записали бы число, меньшее самого маленького в массиве (в нашем случае подойдет 0). Затем нашли бы в изменившемся исходном массиве новое максималь¬ное число и записали его на второе справа место, а на его место в ис¬ходном массиве - 0. И так далее.
Вот программа для 10 чисел:
Const N = 10 'N- размер массива
Dim massi_ishodn(1 То N) As Integer 'Это исходный массив
Dim massiv_rezult( 1 То N) As Integer 'Это наш пустой лист бумаги
'Вспомогательная функция для поиска максимума в массиве m(1 То N).
'Она выдает значение максимального элемента (maximum) и заодно номер
'этого элемента (Nomer_max):
Private Function maximum(m, N As Integer, Nomer_max As Integer) As Integer
Dim i As Integer, max As Integer
max = m(1): Nomer_max = 1 'max- "временный" максимум
For i = 2 To N If max < m(i) Then
max = m(i)
Nomer_max = i
End If
maximum = max
Next
End Function
'Основная процедура сортировки исходного вектора mass_ish размера N
'в результирующий - mass_rez:
Private Sub sortirovka(mass_ish, N As Integer, mass_rez)
Dim Nom_max As Integer
For i = 1 To N
mass_rez(N + 1 - i) = maximum(mass_ish, N, Nom_max) 'Пишем "в правую клетку"
mass_ish(Nom_max) = 0 'Нуль - на старое место
Next
End Sub
Private Sub Command1_Click()
massiv_ishodn(1) = 41 'Задаем значения элементов исходного массива
massiv_ishodn(2) = 8
massiv_ishodn(3) = 17
massiv_ishodn(4) = 82
massiv_ishodn(5) = 20
massiv_ishodn(6) = 2
massiv_ishodn(7) = 30
massiv_ishodn(8) = 12
massiv_ishodn(9) = 6
massiv_ishodn(10) = 9
sortirovka massiv_ishodn, N, massiv_rezult 'Сортируем массив
For i = 1 To N
Print massiv_rezult(i); 'Распечатываем отсортированный массив
Next
End Sub
Функция maximum, кроме того, что сама имеет значение максималь¬ного элемента массива, выдает еще порядковый номер максимального элемента - Nomer_max. Это называется побочным эффектом функции.
Методов сортировки много. Приведенный метод - самый прими¬тивный. Мало того что нам пришлось расходовать память на второй массив, для выполнения сортировки массива из 100 элементов пона¬добилось бы около 100*100=10000 операций сравнения элементов массива между собой.
Существуют методы гораздо более эффективные. Приведу один из них - метод пузырька. Представьте себе тонкую вертикальную труб¬ку с водой. Запустим снизу пузырек воздуха. Он поднимется до само¬го верха и остановится. Затем пустим еще один. Он поднимется на¬верх и остановится сразу же под первым. Затем запустим третий и так далее все 100 пузырьков.
А теперь представим, что это не трубка, а наш исходный массив, а вместо пузырьков поднимаются максимальные элементы.
Вот алгоритм. Сравним первый элемент массива со вторым, и если второй больше, то ничего не делаем, а если первый больше, то меняем местами первый и второй элементы. В этом вся соль метода. Затем по¬вторяем это со вторым и третьим элементами: если третий больше, -то ничего не делаем, а если второй больше, то меняем местами второй и третий элементы. Затем повторяем все это с третьим и четвертым элементами и т. д. Где-то по пути мы встретим максимальный элемент, и он, как пузырек, поднимется у нас до самого верха.
Теперь, когда мы знаем, что элемент номер 100 у нас самый большой, нам предстоит решить задачу сортировки для массива из остальных 99 элементов. Метод тот же. Запускаем второй пузырек и т. д.
Метод пузырька не требует второго массива, да и сравнений здесь
в 2 раза меньше.
Пример:
Dim mass(10) As Integer
Dim i As Integer
Private Sub Command1_Click()
m = 10
Randomize
For i = 1 To m
mass(i) = Rnd * 10
Print mass(i)
Next
For l = m To 2 Step -1
For i = 1 To l - 1
If mass(i) > mass(i + 1) Then 'сравниваем соседние элементы
c = mass(i) 'в ячейку с записываем i-тый элемент
mass(i) = mass(i + 1) ' в i-тую ячейку записывам элемент i+1
mass(i + 1) = c ' в i+1 ячейку записывае i-тый элемент из ячейки c
End If
Next i
Next l
For i = 1 To m
Print "a("; i; ")="; mass(i)
Next i
End Sub